package com.njtoyo.taxi.admin.service.data.impl;

import cn.hutool.core.date.DateUtil;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.njtoyo.taxi.admin.handler.FilterHandler;
import com.njtoyo.taxi.admin.library.Const;
import com.njtoyo.taxi.admin.mapper.secondary.entity.data.DashboardCallMinute;
import com.njtoyo.taxi.admin.mapper.secondary.entity.data.DashboardCustomerMinute;
import com.njtoyo.taxi.admin.mapper.secondary.entity.data.DashboardIncomeMinute;
import com.njtoyo.taxi.admin.mapper.secondary.entity.data.DashboardOrderMinute;
import com.njtoyo.taxi.admin.mapper.secondary.enums.DataIncomeThroughType;
import com.njtoyo.taxi.admin.mapper.secondary.enums.DataOrderType;
import com.njtoyo.taxi.admin.mapper.secondary.mapper.data.DashboardCallMinuteMapper;
import com.njtoyo.taxi.admin.mapper.secondary.mapper.data.DashboardCustomerMinuteMapper;
import com.njtoyo.taxi.admin.mapper.secondary.mapper.data.DashboardIncomeMinuteMapper;
import com.njtoyo.taxi.admin.mapper.secondary.mapper.data.DashboardOrderMinuteMapper;
import com.njtoyo.taxi.admin.rest.wrapper.data.rank.TodayRankWrapper;
import com.njtoyo.taxi.admin.service.data.TodayRankService;
import com.taxi.entity.common.RestResult;
import com.njtoyo.taxi.entity.backend.AdminUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

@Service
@DS(Const.SECONDARY_DS)
public class TodayRankServiceImpl implements TodayRankService {

    @Autowired
    private DashboardOrderMinuteMapper dashboardOrderMinuteMapper;

    @Autowired
    private DashboardIncomeMinuteMapper dashboardIncomeMinuteMapper;

    @Autowired
    private DashboardCallMinuteMapper dashboardCallMinuteMapper;

    @Autowired
    private DashboardCustomerMinuteMapper dashboardCustomerMinuteMapper;

    @Override
    public RestResult order(AdminUser adminUser, TodayRankWrapper wrapper) {
        return RestResult.success(getOrderData(adminUser, wrapper));
    }

    List<Map<String, Object>> getOrderData(AdminUser adminUser, TodayRankWrapper wrapper) {
        Date end = new Date();
        Date start = DateUtil.beginOfDay(end);
        FilterHandler filterHandler = new FilterHandler(adminUser, wrapper.getCantonId(), null);

        QueryWrapper<DashboardOrderMinute> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("type", DataOrderType.pickOnline, DataOrderType.pickScan, DataOrderType.simpleCall, DataOrderType.phoneCall);
        queryWrapper.in("is_imitate", filterHandler.getIsImitates());

        switch (filterHandler.getFilterType()) {
            case canton:
                queryWrapper.in("canton_id", filterHandler.getCantonIds());
                break;
            case company:
                queryWrapper.in("company_id", filterHandler.getCompanyIds());
                break;
        }

        // 按公司
        if (Objects.nonNull(wrapper.getCantonId())) {
            queryWrapper.select("IFNULL(SUM(num), 0) as total, company_id");
            queryWrapper.groupBy("company_id");
        } else {
            queryWrapper.select("IFNULL(SUM(num), 0) as total, canton_id");
            queryWrapper.groupBy("canton_id");
        }
        queryWrapper.orderByDesc("total");
        queryWrapper.between("stats_date", start, end);

        List<Map<String, Object>> result = dashboardOrderMinuteMapper.selectMaps(queryWrapper);

        // 倍率设置
        Double ride = filterHandler.getFakeMultiple().getRide();
        if (Objects.nonNull(ride)) {
            for (int i = 0; i < result.size(); i++) {
                Map<String, Object> item = result.get(i);
                item.put("total", (long)(Long.parseLong(item.get("total").toString()) * ride));
                result.set(i, item);
            }
        }
        return result;
    }

    @Override
    public RestResult income(AdminUser adminUser, TodayRankWrapper wrapper) {
        Date end = new Date();
        Date start = DateUtil.beginOfDay(end);
        FilterHandler filterHandler = new FilterHandler(adminUser, wrapper.getCantonId(), null);

        QueryWrapper<DashboardIncomeMinute> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("is_imitate", filterHandler.getIsImitates())
                .eq("through_type", DataIncomeThroughType.all);

        switch (filterHandler.getFilterType()) {
            case canton:
                queryWrapper.in("canton_id", filterHandler.getCantonIds());
                break;
            case company:
                queryWrapper.in("company_id", filterHandler.getCompanyIds());
                break;
        }

        // 按公司
        if (Objects.nonNull(wrapper.getCantonId())) {
            queryWrapper.select("IFNULL(SUM(value), 0) as total, company_id");
            queryWrapper.groupBy("company_id");
        } else {
            queryWrapper.select("IFNULL(SUM(value), 0) as total, canton_id");
            queryWrapper.groupBy("canton_id");
        }
        queryWrapper.orderByDesc("total");
        queryWrapper.between("stats_date", start, end);

        List<Map<String, Object>> result = dashboardIncomeMinuteMapper.selectMaps(queryWrapper);

        // 倍率设置
        Double ride = filterHandler.getFakeMultiple().getRide();
        if (Objects.nonNull(ride)) {
            for (int i = 0; i < result.size(); i++) {
                Map<String, Object> item = result.get(i);
                item.put("total", Double.parseDouble(item.get("total").toString()) * ride);
                result.set(i, item);
            }
        }

        return RestResult.success(result);
    }

    @Override
    public RestResult call(AdminUser adminUser, TodayRankWrapper wrapper) {
        Date end = new Date();
        Date start = DateUtil.beginOfDay(end);
        FilterHandler filterHandler = new FilterHandler(adminUser, wrapper.getCantonId(), null);

        QueryWrapper<DashboardCallMinute> queryWrapper = new QueryWrapper<>();
        switch (filterHandler.getFilterType()) {
            case canton:
            case company:
                queryWrapper.in("canton_id", filterHandler.getCantonIds());
                break;
        }
        queryWrapper.between("stats_date", start, end);
        queryWrapper.select("IFNULL(SUM(num), 0) as total, canton_id");
        queryWrapper.groupBy("canton_id");
        queryWrapper.orderByDesc("total");

        List<Map<String, Object>> res = dashboardCallMinuteMapper.selectMaps(queryWrapper);
        // 倍率设置
        Double ride = filterHandler.getFakeMultiple().getCall();
        if (Objects.nonNull(ride)) {
            List<Map<String, Object>> rideList = getOrderData(adminUser, wrapper);
            Map<String, Long> rideMap = rideList.stream().filter(i -> Objects.nonNull(i.get("cantonId"))).collect(Collectors.toMap(i -> i.get("cantonId").toString(), i -> (long)i.get("total")));
            for (int i = 0; i < res.size(); i++) {
                Map<String, Object> item = res.get(i);
                if (Objects.isNull(item.get("cantonId"))) {
                    break;
                }
                long callCount = (long) (Long.parseLong(item.get("total").toString()) * ride);
                long rideCount = rideMap.getOrDefault(item.get("cantonId").toString(), 0L);
                if (callCount < rideCount) {
                    callCount = (long) (rideCount * 1.215);
                }
                res.get(i).put("total", callCount);
            }
        }

        return RestResult.success(res);
    }

    @Override
    public RestResult customer(AdminUser adminUser, TodayRankWrapper wrapper) {
        Date end = new Date();
        Date start = DateUtil.beginOfDay(end);
        FilterHandler filterHandler = new FilterHandler(adminUser, wrapper.getCantonId(), null);

        QueryWrapper<DashboardCustomerMinute> queryWrapper = new QueryWrapper<>();
        switch (filterHandler.getFilterType()) {
            case canton:
            case company:
                queryWrapper.in("canton_id", filterHandler.getCantonIds());
                break;
        }
        queryWrapper.between("stats_date", start, end);
        queryWrapper.select("IFNULL(SUM(num), 0) as total, canton_id");
        queryWrapper.groupBy("canton_id");
        queryWrapper.orderByDesc("total");

        List<Map<String, Object>> result = dashboardCustomerMinuteMapper.selectMaps(queryWrapper);
        Double customer = filterHandler.getFakeMultiple().getCustomer();
        if (Objects.nonNull(customer)) {
            for (int i = 0; i < result.size(); i++) {
                Map<String, Object> item = result.get(i);
                item.put("total", (long)(Long.parseLong(item.get("total").toString()) * customer));
                result.set(i, item);
            }
        }

        return RestResult.success(result);
    }
}
